#encoding=utf-8
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys
from FC22UartUpdateTools import Ui_FC22UartUpdateTools
from FC22UartUpdateTools import *
# IMPORT FUNCTIONS
from ui_functions import *
import os
import serial.tools.list_ports
import re
import subprocess
# ---------------------------------- 工作线程 -------------------------------------
class WorkThread(QThread):
    trigger = pyqtSignal(str)
    triggerPorcessContent = pyqtSignal(str)
    triggerPorcess = pyqtSignal(int)

    def __int__(self):
        super(WorkThread, self).__init__()
        self.downloadcmd = "."

    def setDirpath(self, dirpath):
        self.downloadcmd = dirpath

    def run(self):
        # 通过子进程进行烧录工作
        BianMa = "ascii"
        try:
            print("subprocess Popen:" + self.downloadcmd)
            proc = subprocess.Popen(self.downloadcmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
                                    encoding=BianMa)
            while not proc.poll():
                buff = proc.stdout.readline().encode(BianMa)
                # if buff == b'' and proc.poll() != None:
                print(buff)
                if buff == b'':
                    break
                else:
                    if re.match(r"^Sending", buff.decode(BianMa)):
                        print("匹配成功")
                        # 提取进入条
                        matchstr = re.search(r"\d+%", buff.decode(BianMa))
                        if matchstr:
                            process = matchstr.group()
                            process = process.strip('%')
                            self.triggerPorcess.emit(int(process))
                    else:
                        self.triggerPorcessContent.emit(buff.decode(BianMa))
        except Exception as e:
            print("downloadcmd Exception:" + str(e))
        finally:
            print("finish")

class MWin(QWidget, Ui_FC22UartUpdateTools):
    def __init__(self, parent=None):
        super(MWin, self).__init__(parent)
        self.setupUi(self)
        self.initFileMemu()
        self.connectSlots()
        self.workThread = WorkThread()
        # 当获得循环完毕的信号时，停止计数
        self.workThread.trigger.connect(self.waitprocessFinishTime)
        self.workThread.triggerPorcessContent.connect(self.waitprocessContext)
        self.workThread.triggerPorcess.connect(self.waitprocessShow)
        ## SHOW ==> MAIN WINDOW
        ########################################################################
        self.show()

    def initFileMemu(self):
        # MOVE WINDOW
        def moveWindow(event):
            # RESTORE BEFORE MOVE
            if UIFunctions.returnStatus() == 1:
                UIFunctions.maximize_restore(self)


            # IF LEFT CLICK MOVE WINDOW
            if event.buttons() == Qt.LeftButton:
                self.move(self.pos() + event.globalPos() - self.dragPos)
                self.dragPos = event.globalPos()
                event.accept()

        # SET TITLE BAR
        self.title_bar.mouseMoveEvent = moveWindow

        ## ==> SET UI DEFINITIONS
        UIFunctions.uiDefinitions(self)

    def mousePressEvent(self, event):
        self.dragPos = event.globalPos()

    def enterEvent(self, evt):
        # print("鼠标进来了", self.y())
        if self.y() == (-1.0*(self.height()-2)):
        # if self.y() == -498:
        #     print(self.y())
            try:
                # 开启动画
                animation = QPropertyAnimation(self, b"pos", self)
                animation.setStartValue(QPoint(self.x(), self.y()))
                animation.setEndValue(QPoint(self.x(), 0))
                animation.setDuration(200)
                animation.start()
            except Exception as e:
                print(e)

    def leaveEvent(self, evt):
        # print("鼠标离开了", self.y())
        if self.y() <= 0:
            try:
                # 开启动画
                animation = QPropertyAnimation(self, b"pos", self)
                animation.setStartValue(QPoint(self.x(), self.y()))
                y = -1*(self.height()-2)
                # print("likai:", y)
                animation.setEndValue(QPoint(self.x(), y))
                animation.setDuration(200)
                animation.start()
            except Exception as e:
                print(e)

    ## APP EVENTS
    ########################################################################
    def connectSlots(self):
        self.Btn_clear.clicked.connect(self.clearText)
        self.Btn_Start.clicked.connect(self.updateImage)
        self.Btn_openBootFile.clicked.connect(self.openBootFileSolts)
        self.Btn_OpenApp1.clicked.connect(self.Btn_OpenApp1Slots)
        self.btn_UartRefresh.clicked.connect(self.btn_UartRefreshSolts)

    def clearText(self):
        self.textEdit.clear()
        pass

    def btn_UartRefreshSolts(self):
        self.comboBox.clear()
        # 获取所有的串口名
        com_list = serial.tools.list_ports.comports()
        for com in com_list:
            self.comboBox.addItem(com.description)
        pass

    # 在全局的serial_name_list 中 查找 description
    def find_device_by_name(self, name):
        # 获取所有的串口名
        com_list = serial.tools.list_ports.comports()
        for com in com_list:
            if com.description == name:
                return com.device

        return None

    def openBootFileSolts(self):
        passwd, ok = QInputDialog.getText(self, 'PassWd Input', 'Please enter the Passwd:')
        if ok:
            if passwd != "desaysv":
                self.textEdit.append("输入的密码错误:" + passwd)
                return
            else:
                self.textEdit.append("输入的密码正确")
        else:
            self.textEdit.append("取消输入的密码")
            return

        file, _ = QFileDialog.getOpenFileName(self, 'Select Boot File', './', 'Files (*.tiimage)')
        if file:
            self.lineEdit_BootFile.setText(file)
            self.textEdit.append("Boot File Path:" + file)
        else:
            self.textEdit.append("No Select Boot File Path")
            return

    def Btn_OpenApp1Slots(self):
        file, _ = QFileDialog.getOpenFileName(self, 'Select App File', './', 'Files (*.appimage)')
        if file:
            self.lineEdit_OpenApp1.setText(file)
            self.textEdit.append("App File Path:" + file)
        else:
            self.textEdit.append("No Select App File Path")
            return

    def waitprocessFinishTime(self, time):
        print("waitprocessFinish")
        self.textEdit.setText(str(time))

    def waitprocessShow(self, val):
        print("waitprocessFinish waitprocessContext")
        # self.textEdit.append("proces:" + str(val))
        self.progressBar.setValue(val)

    def waitprocessContext(self, text):
        print("waitprocessFinish waitprocessContext")
        self.textEdit.append(text)
        self.textEdit.moveCursor(QTextCursor.End)

    def updateImage(self):
        try:
            BootFilePath = self.lineEdit_BootFile.text()
            BootFileOffset = self.lineEdit_BootFileOffset.text()
            BootFileOffset_Number = 0

            OpenApp1Path = self.lineEdit_OpenApp1.text()
            OpenApp1Offset = self.lineEdit_OpenApp1Offset.text()
            OpenApp1Offset_Number = 0

            COMNUM = None

            try:
                BootFileOffset = BootFileOffset.replace(" ", "")  # 去除空格
                BootFileOffset = BootFileOffset.replace("0x", "")  # 去除前缀0x（如果有）
                BootFileOffset_Number = int(BootFileOffset, 16)
                self.textEdit.append("BootFileOffset 转换结果为："+ str(BootFileOffset_Number))
            except Exception as e:
                self.textEdit.append("BootFileOffset 转换失败 退出")
                return

            try:
                OpenApp1Offset = OpenApp1Offset.replace(" ", "")  # 去除空格
                OpenApp1Offset = OpenApp1Offset.replace("0x", "")  # 去除前缀0x（如果有）
                OpenApp1Offset_Number = int(OpenApp1Offset, 16)
                self.textEdit.append("OpenApp1Offset 转换结果为：" + str(OpenApp1Offset_Number))
            except Exception as e:
                self.textEdit.append("OpenApp1Offset 转换失败 退出")
                return

            if os.path.exists(BootFilePath):
                self.textEdit.append("BootFilePath:" + BootFilePath + "存在")
            else:
                self.textEdit.append("BootFilePath:" + BootFilePath + "不存在 退出")
                return

            if os.path.exists(OpenApp1Path):
                self.textEdit.append("OpenApp1Path:" + OpenApp1Path + "存在")
            else:
                self.textEdit.append("OpenApp1Path:" + OpenApp1Path + "不存在 退出")
                return

            selectNamne = self.comboBox.currentText()
            if selectNamne:
                self.textEdit.append("选择串口号  " + selectNamne)
                COMNUM = self.find_device_by_name(selectNamne)
                print(COMNUM)
                if COMNUM:
                    self.textEdit.append(COMNUM)
                else:
                    self.textEdit.append("串口已经拔出 退出")

            else:
                self.textEdit.append("请刷新并选择串口号 退出")
                return

            # 进行烧录脚本制作
            lines_to_keep = None
            lines_to_keep = "--flash-writer=" + self.lineEdit.text() + "\r\n"
            lines_to_keep += "--file="+ self.lineEdit_BootFile.text() + " --operation=flash --flash-offset="+ self.lineEdit_BootFileOffset.text() + "\r\n"
            lines_to_keep += "--file="+ self.lineEdit_OpenApp1.text() + " --operation=flash --flash-offset="+ self.lineEdit_OpenApp1Offset.text() + "\r\n"
            self.textEdit.append(lines_to_keep)
            with open("temp.cfg", "w") as fp:
                # 清空文件内容
                fp.seek(0)  # 将文件指针移动到文件的开头
                fp.truncate()  # 清空文件内容
                fp.writelines(lines_to_keep)

            downloadcmd = "uart_uniflash.exe -p "+ COMNUM +" --cfg=temp.cfg"
            self.textEdit.append(downloadcmd)

            # 通过线程控制进程进行烧录工作
            self.workThread.setDirpath(downloadcmd)
            self.workThread.start()

        except Exception as e:
            self.textEdit.append("异常"+str(e))






if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MWin()
    # try:
    #     qssfile = open("./qss/style.qss", encoding='utf-8')
    #     qssStyle = qssfile.read()
    #     qssfile.close()
    #     w.setStyleSheet(qssStyle)
    # except Exception as e:
    #     print(e)
    w.show()
    sys.exit(app.exec_())